﻿//Copyright © 2012 by Geodata Danmark. All Rights Reserved
//Author: Carsten Helsted


using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Microsoft.Win32;
using System.Text.RegularExpressions;
using System.IO;

namespace BrowseByURL
{
    static class Program
    {
        public const string InstalledBrowsersKey = @"SOFTWARE\\Clients\\StartMenuInternet";
        public const string BrowseByUrlKey = @"SOFTWARE\\Geodata Danmark\\BrowseByURL";
        public const string UserChoiceHTTP = @"Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice";
        public const string UserChoiceHTTPS = @"Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\https\\UserChoice";

        public const string ProtocolHTTP = @"http\shell\open\command";
        public const string ProtocolHTTPS = @"https\shell\open\command";

        private static List<Browser> _installedBrowsers = null;
        private static List<URLDef> _urlDefinitions = null;


        public static List<Browser> InstalledBrowsers
        {
            get
            {
                return _installedBrowsers;
            }
            set
            {
                _installedBrowsers = value;
            }
        }

        public static List<URLDef> UrlDefinitions
        {
            get
            {
                return _urlDefinitions;
            }
            set
            {
                _urlDefinitions = value;
            }
        }

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            _installedBrowsers = getAvailableBrowsers();
            _urlDefinitions = getURLDefinitions(_installedBrowsers);


            if (args.Length > 0 && args[0].Equals("/ADMIN", StringComparison.CurrentCultureIgnoreCase))
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new frmMain());
            }
            else
            {
                bool launched = false;

                string requestedURL = "";
                if(args.Length > 0)
                    requestedURL = args[0];

                try
                {

                    foreach (URLDef u in _urlDefinitions)
                    {
                        RegexOptions myRegexOptions = RegexOptions.IgnoreCase;

                        Regex searchTerm = new Regex(u.URLExp, myRegexOptions);
                        foreach (Match m in searchTerm.Matches(requestedURL))
                        {
                            if (m.Success)
                            {
                                // Start the real browser
                                System.Diagnostics.Process proc = new System.Diagnostics.Process();
                                proc.EnableRaisingEvents = false;
                                proc.StartInfo.FileName = String.Format(@"{0}", u.UseBrowser.ShellCommand);
                                proc.StartInfo.Arguments = String.Format(@"{0}", requestedURL);
                                proc.Start();
                                launched = true;

                                break;
                            }
                        }
                        if (launched)
                            break;

                    }
                }
                catch (Exception ex)
                {
                    //Something went wrong. Switch to the default browser.
                    System.Diagnostics.Debug.WriteLine(ex, "Failure");
                    launched = false;

                }
                if(!launched)
                    LaunchDefaultBrowser(requestedURL);
            }
        }

        public static void LaunchDefaultBrowser(string requestedURL)
        {
            Browser defBrowser = null;
            foreach (Browser b in _installedBrowsers)
            {
                if (b.IsDefaultBrowser)
                {
                    defBrowser = b;
                    break;
                }
            }

            if (defBrowser != null)
            {
                try
                {
                    System.Diagnostics.Process proc = new System.Diagnostics.Process();
                    proc.EnableRaisingEvents = false;
                    proc.StartInfo.FileName = String.Format(@"{0}", defBrowser.ShellCommand);
                    proc.StartInfo.Arguments = String.Format(@"{0}", requestedURL);
                    proc.Start();
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex, "FailureDefault");
                }
            }
        }

        public static List<URLDef> getURLDefinitions(List<Browser> browserList)
        {
            List<URLDef> urlDefList = new List<URLDef>();
            RegistryKey key = Registry.CurrentUser.OpenSubKey(Program.BrowseByUrlKey);
            if (key != null)
            {
                foreach (Browser b in browserList)
                {
                    Console.WriteLine(b.Name);


                    RegistryKey browserKey = key.OpenSubKey(b.Name);
                    if (browserKey != null)
                    {
                        foreach (string s in browserKey.GetValueNames())
                        {
                            string urlExp = browserKey.GetValue(s).ToString();
                            if (urlExp != null)
                            {
                                URLDef u = new URLDef(urlExp, b);
                                urlDefList.Add(u);
                            }
                        }
                    }
                }
            }
            return urlDefList;
        }


        public static List<Browser> getAvailableBrowsers()
        {
            bool defaultBrowserIsSet = false;
            string assemblyFilename = Path.GetFileName(System.Reflection.Assembly.GetEntryAssembly().Location);


            List<Browser> browserList = new List<Browser>();
            RegistryKey key = Registry.LocalMachine.OpenSubKey(Program.InstalledBrowsersKey);
            if (key != null)
            {
                foreach (var v in key.GetSubKeyNames())
                {
                    Console.WriteLine(v);


                    RegistryKey browserKey = key.OpenSubKey(v);
                    if (browserKey != null && !v.ToString().Equals(assemblyFilename, StringComparison.CurrentCultureIgnoreCase))
                    {
                        //Get Browsers DisplayName
                        string displayName = browserKey.GetValue(null).ToString();

                        //Get Browsers ShellCommand
                        string shellCommand = browserKey.OpenSubKey("shell").OpenSubKey("open").OpenSubKey("command").GetValue(null).ToString();


                        //Get Browsers DefaultIcon
                        string defaultIcon = browserKey.OpenSubKey("DefaultIcon").GetValue(null).ToString().Split(',')[0];


                        //Check if Browser is Default
                        bool isDefaultBrowser = false;
                        RegistryKey urlKey = Registry.CurrentUser.OpenSubKey(Program.BrowseByUrlKey);
                        if (urlKey!=null)
                        {
                            string defaultBrowser = urlKey.GetValue("DEFAULT_BROWSER").ToString();
                            if (defaultBrowser != null && defaultBrowser.Equals(v, StringComparison.CurrentCultureIgnoreCase))
                            {
                                isDefaultBrowser = true;
                                defaultBrowserIsSet = true;
                            }
                        }


                        Browser b = new Browser(v, displayName, shellCommand, defaultIcon, isDefaultBrowser);

                        browserList.Add(b);
                    }

                }

                //Force a default browser if non specified.
                if (!defaultBrowserIsSet && browserList.Count > 0)
                    browserList[0].IsDefaultBrowser = true;
            }
            return browserList;
        }
    }
}
